package com.franklin.ideaplugin.easytesting.rpc;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.franklin.ideaplugin.easytesting.registry.ApplicationScheduleFileRegistry;
import com.franklin.ideaplugin.easytesting.rpc.entity.RegistryData;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 注册中心
 *
 * @author Ye Junhui
 * @since 2023/5/20
 */
public class RegistryCenter {

    /**
     * 获取方法注册的本地服务
     * @param containingFile
     * @return
     */
    public static List<RegistryData> getRegistryLocal(PsiFile containingFile){
        // TODO: 2023/5/15 兼容gradle
        String path = containingFile.getVirtualFile().getPath();
        if (!path.contains("/src/main/java")){
            return Collections.emptyList();
        }
        int index = path.indexOf("/src/main/java");
        path = path.substring(0,index);
        String serviceName = getPathServiceName(path);
        String registryServicePath = getRegistryServicePath(containingFile.getProject(), serviceName);
        if (StrUtil.isBlank(registryServicePath)){
            return Collections.emptyList();
        }
        return getRegistryData(containingFile.getProject(), registryServicePath);
    }

    /**
     * 获取注册方法的路径
     * @param serviceName
     * @return
     */
    public static String getRegistryServicePath(Project project,String serviceName){
        return getProjectRegistryPath(project) + "/" + serviceName;
    }

    /**
     * 项目注册路径
     * @param project
     * @return
     */
    public static String getProjectRegistryPath(Project project){
        String projectBasePath = project.getBasePath();
        return projectBasePath + "/.idea/etServer/serviceList";
    }

    /**
     * 获取注册的所有服务
     * @param containingFile
     * @return
     */
    public static List<RegistryData> getRegisterServer(PsiFile containingFile){
        if (Objects.isNull(containingFile)){
            return Collections.emptyList();
        }
        PsiFile originalFile = containingFile.getOriginalFile();
        PsiDirectory containingDirectory = originalFile.getContainingDirectory();
        if (Objects.isNull(containingDirectory)){
            return Collections.emptyList();
        }
        String path = containingDirectory.getVirtualFile().getCanonicalPath();
        if (StrUtil.isBlank(path)){
            return Collections.emptyList();
        }
        Project project = containingFile.getProject();
        if (path.contains(".jar")){
            return registryDataJar(project, path);
        }
        if (path.contains(".zip")){
            return registryDataZip(project, path);
        }
        if (path.contains("/src/main/java")){
            return getRegistryLocal(containingFile);
        }
        return Collections.emptyList();
    }

    /**
     * jar包注册
     * @param path
     * @return
     */
    private static List<RegistryData> registryDataJar(Project project,String path){
        int index = path.indexOf(".jar");
        path = path.substring(0,index + 4);
        String registryPath = getPathServiceName(path);
        String registryServicePath = getRegistryServicePath(project, registryPath);
        return getRegistryData(project, registryServicePath);
    }

    public static String getPathServiceName(String path){
        return path
                .replace("/", "_")
                .replace("\\", "_")
                .replace(":", "_")
                .replace('<','(')
                .replace('>',')')
                .replace('.','_')
                .replace("-sources","");
    }

    /**
     * zip包注册
     * @param path
     * @return
     */
    private static List<RegistryData> registryDataZip(Project project,String path){
        String str = "src.zip";
        int index = path.indexOf(str);
        path = path.substring(0,index + str.length());
        String registryPath = path;
        registryPath = getPathServiceName(registryPath);
        String registryServicePath = getRegistryServicePath(project, registryPath);
        return getRegistryData(project, registryServicePath);
    }

    @NotNull
    private static List<RegistryData> getRegistryData(Project project,String registryPath) {
        return ApplicationScheduleFileRegistry.getRegistryData(project, registryPath);
    }
}
